package com.ji.li.reactadminproexampleservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ji.li.reactadminproexampleservice.dto.UserLogin;
import com.ji.li.reactadminproexampleservice.entity.http.ResEntity;
import com.ji.li.reactadminproexampleservice.entity.http.ResEnum;
import com.ji.li.reactadminproexampleservice.entity.menu.Menu;
import com.ji.li.reactadminproexampleservice.entity.menu.MenuRole;
import com.ji.li.reactadminproexampleservice.entity.menu.MenuUserRole;
import com.ji.li.reactadminproexampleservice.entity.menu.Role;
import com.ji.li.reactadminproexampleservice.entity.user.User;
import com.ji.li.reactadminproexampleservice.entity.auth.AuthUserRole;
import com.ji.li.reactadminproexampleservice.service.*;
import com.ji.li.reactadminproexampleservice.utils.type.CurrentUserUtils;
import com.ji.li.reactadminproexampleservice.utils.type.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ApiServiceImpl implements ApiService {
    private static final String Authorization = "Authorization";
    private final JsonUtils jsonUtils;
    private final CurrentUserUtils currentUserUtils;
    private final AuthService authService;
    private final MapperService mapperService;

    @Autowired
    public ApiServiceImpl(JsonUtils jsonUtils, CurrentUserUtils currentUserUtils,
                          AuthService authService, MapperService mapperService) {
        this.jsonUtils = jsonUtils;
        this.currentUserUtils = currentUserUtils;
        this.authService = authService;
        this.mapperService = mapperService;
    }

    /**
     * 用户 账号 登录 方式
     * @param dto 请求body
     * @return 返回body
     */
    @Override
    public ResponseEntity<ResEntity> adminLoginAccount(UserLogin dto) {
        List<Object> loginRes =
                mapperService.adminLoginAccount(dto.getUserName(),dto.getPassWord());
        ResEntity res = new ResEntity();
        if ((Boolean) loginRes.get(0)) {
            User user = (User) loginRes.get(1);
            setUserRoles(user);
            String token = authService.createToken(user, dto.getRememberMe());
            HttpHeaders headers = new HttpHeaders();
            headers.set(Authorization, token);
            res.setCodeAndMessage(ResEnum.SUCCESS);
            res.setData((JSONObject) jsonUtils.Bean2Json(headers));
            return ResponseEntity.ok().headers(headers).body(res);
        } else {
            res.setCodeAndMessage(ResEnum.LOGIN_ERROR);
            return ResponseEntity.ok().body(res);
        }
    }

    /**
     * 获取 当前 用户
     * @return 用户信息（包含权限）
     */
    @Override
    public ResponseEntity<ResEntity> getCurrentUser() {
        User user = mapperService.findUserByName(currentUserUtils.getCurrentUser());
        setUserRoles(user);
        setUserMenus(user);
        return ResponseEntity.ok().body(
                new ResEntity(ResEnum.SUCCESS,jsonUtils.Bean2Json(user)));
    }

    /**
     * 用户 退出 当前登录状态
     */
    @Override
    public void adminLoginOut() {
        authService.removeToken();
    }

    /**
     * 设置 用户 接口权限
     */
    private void setUserRoles(User user) {
        List<AuthUserRole> authUserRoles =
                mapperService.selectUserRoles(user.getuId());
        for (AuthUserRole authUserRole : authUserRoles) {
            authUserRole.setUser(mapperService.setUser(authUserRole.getUserId()));
            authUserRole.setRole(mapperService.setRole(authUserRole.getRoleId()));
        }
        user.setUserRoles(authUserRoles);
    }

    /**
     * 设置 用户 菜单权限
     *  menuUserRole.size() 对应该用户 拥有 几个 菜单角色组 权限
     */
    private void setUserMenus(User user) {
        ArrayList<MenuUserRole> menuUserRoles = (ArrayList<MenuUserRole>)
                mapperService.selectMenuUserRole(user.getuId());
        if (!menuUserRoles.isEmpty()) {
            ArrayList<Integer> roleIds = (ArrayList<Integer>)
                    menuUserRoles.stream().map(MenuUserRole::getRoleId).collect(Collectors.toList());
            ArrayList<Role> roles = (ArrayList<Role>) mapperService.selectRole(roleIds);
            user.setRole(roles);
            ArrayList<MenuRole> menuRoles = new ArrayList<>();
            for(Integer roleId : roleIds) {
                ArrayList<MenuRole> itemMenuRoles = (ArrayList<MenuRole>)
                        mapperService.selectMenuRole(roleId);
                menuRoles.addAll(itemMenuRoles);
            }
            if (!menuRoles.isEmpty()) {
                ArrayList<Integer> menuIds = (ArrayList<Integer>)
                        menuRoles.stream().map(MenuRole::getMenuId).collect(Collectors.toList());
                ArrayList<Menu> menus = (ArrayList<Menu>) mapperService.selectMenus(
                                menuIds.stream().distinct().collect(Collectors.toList()));
                user.setMenu(menus);
            }
        }
    }
}
